#include "CQuadtree.h"

CQuadtree::CQuadtree()
{
	_rootNode = NULL;	
}

CQuadtree::~CQuadtree()
{
	if (_rootNode!=NULL)
		delete _rootNode;
	_rootNode = NULL;
}

CQuadtree::CQuadtree(CRect Rectworld)
{
	_rootNode = new QNode(0,Rectworld);
}

void CQuadtree::Insert(list<GameObject*> listGameObjects)
{
	list<GameObject*>::iterator it;
	for(it=listGameObjects.begin(); it!=listGameObjects.end(); ++it)
		if((*it)->GetObjectState()!=EState::Die )
		{
			EObjectType _type=(*it)->GetObjectType();
			switch (_type)
			{
			case EMushroom_Red:
			case EMushroom_Green:
			case EFlower:
			case EFungi:			
			case ETurtle:			
			case EStar:
			case EBullet:
				_rootNode->Insert(*it);
				break;	
			}			
		}
}

void CQuadtree::GetObjects(CRect viewport, QNode* node)
{	
	// leaf node

	if(!node->_tl)
	{ 
		if( node->getBound().intersectsRect(viewport) == true) 
		{			
			list<GameObject*> _listObjects=node->getListGameObjects();
			for(list<GameObject*>::iterator it=_listObjects.begin(); it!=_listObjects.end(); ++it)
			{
				if((*it)->GetObjectState()!=Die)
					_viewportObjects.push_back(*it);
			}
			//copy(node->getListGameObjects().begin(), node->getListGameObjects().end(), back_inserter(_viewportObjects));		
		}
	}
	else 
	{
		if(node->_tl->getBound().intersectsRect(viewport))
			GetObjects(viewport,node->_tl);
		if(node->_tr->getBound().intersectsRect(viewport))
			GetObjects(viewport,node->_tr);
		if(node->_bl->getBound().intersectsRect(viewport))
			GetObjects(viewport,node->_bl);
		if(node->_br->getBound().intersectsRect(viewport))
			GetObjects(viewport,node->_br);
	}	
}

list<GameObject*> CQuadtree::GetObjectsInViewport(CRect viewport)
{	
	_viewportObjects.clear();
	this->GetObjects(viewport, _rootNode);
	// loai bo trung lap doi tuong
	//set<GameObject*> mySet;
	//copy(_viewportObjects.begin(), _viewportObjects.end(), inserter(mySet, mySet.begin()));
	//_viewportObjects.clear();
	//copy(mySet.begin(), mySet.end(), back_inserter(_viewportObjects));
	_viewportObjects.sort();
	_viewportObjects.unique();
	return _viewportObjects;
}

// gets, sets
QNode* CQuadtree::getRootNode()
{
	return _rootNode;
}

void CQuadtree::setRootNode(QNode* p)
{
	_rootNode = p;
}

list<GameObject*> CQuadtree::GetColisionObject(CRect rect)
{
	_colObjects.clear();
	this->GetCol(rect, _rootNode);
	// loai bo trung lap doi tuong
	_colObjects.sort();
	_colObjects.unique();
	return _colObjects;
}

void CQuadtree::GetCol(CRect viewport, QNode* node)
{	
	// leaf node
	if(!node->_tl)  
	{ 
		if( node->getBound().intersectsRect(viewport) == true) 
		{			
			list<GameObject*> _listObjects=node->GetAllObjects();			
			for(list<GameObject*>::iterator it=_listObjects.begin(); it!=_listObjects.end(); ++it)
			{
				if((*it)->GetObjectState()!=Die)
					_colObjects.push_back(*it);
			}
			//copy(node->getListGameObjects().begin(), node->getListGameObjects().end(), back_inserter(_viewportObjects));		
		}
	}
	else 
	{
		if(node->_tl->getBound().intersectsRect(viewport))
			GetCol(viewport,node->_tl);
		if(node->_tr->getBound().intersectsRect(viewport))
			GetCol(viewport,node->_tr);
		if(node->_bl->getBound().intersectsRect(viewport))
			GetCol(viewport,node->_bl);
		if(node->_br->getBound().intersectsRect(viewport))
			GetCol(viewport,node->_br);
	}	
}
